package com.zlzlib.libnetty.ws;


import com.zlzlib.libnetty.base.BaseChannelInitializer;
import com.zlzlib.libnetty.listener.WebSocketListener;
import com.zlzlib.libnetty.ws.handler.WebSocketClientHandler;

import java.net.URI;

import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketClientCompressionHandler;

/**
 * Created by zlz on 2019/11/19.
 * webSocket
 * Channel初始化配置
 */
public class WebChannelInitializer extends BaseChannelInitializer<SocketChannel> {

    private final WebSocketListener socketListener;
    private WebSocketClientHandler handler;
    private final HttpHeaders headers;
    private final URI webUrl;

    public WebChannelInitializer(WebSocketListener socketListener, URI url, HttpHeaders headers) {
        this.socketListener = socketListener;
        this.headers = headers;
        webUrl = url;
    }

    @Override
    protected void initChannel(SocketChannel channel) throws Exception {
        //握手handler
        WebSocketClientHandshaker hand = WebSocketClientHandshakerFactory.newHandshaker(
                webUrl, WebSocketVersion.V13, null, true, headers, Integer.MAX_VALUE);
        //数据接收解析handler
        handler = new WebSocketClientHandler(hand, socketListener);
        ChannelPipeline p = channel.pipeline();
        //使用http解编码器
        p.addLast(new HttpClientCodec())
                //netty是基于分段请求的，HttpObjectAggregator的作用是将请求分段再聚合,参数是聚合字节的最大长度
                .addLast(new HttpObjectAggregator(64 * 1024))
                .addLast(WebSocketClientCompressionHandler.INSTANCE)
                .addLast(handler);
    }

    public void handshakeFuture() throws Exception {
        this.handler.handshakeFuture().sync();
    }

    public URI getWebUrl() {
        return webUrl;
    }
}
